      MODULE INOUT_DRIVER_PARAMETERS
      
      integer(4), parameter :: driver_subr_unit_min = 10001
      integer(4), parameter :: driver_subr_unit_max = 11000
      
      END MODULE INOUT_DRIVER_PARAMETERS


      MODULE LAKE_DRIVER_PARAMETERS

      use INOUT_DRIVER_PARAMETERS, only : &
      & driver_subr_unit_min, &
      & driver_subr_unit_max

      integer(4), parameter :: n_select_call = 20

      integer(4), private :: nunit = driver_subr_unit_min
      character(len=200), private :: line = 'begin_file'

      real(8), private :: hour0 ; logical, private :: ok_hour0 = .false.
      real(8), private :: tinteg ; logical, private :: ok_tinteg = .false.
      real(8), private :: dt ; logical, private :: ok_dt = .false.
      real(8), private :: height_T_q ; logical, private :: ok_height_T_q = .false.
      real(8), private :: height_u ; logical, private :: ok_height_u = .false.
      real(8), private :: interval ; logical, private :: ok_interval = .false.
      
      real(8), private :: h10 ; logical, private :: ok_h10 = .false.
      real(8), private :: l10 ; logical, private :: ok_l10 = .false.
      real(8), private :: ls10 ; logical, private :: ok_ls10 = .false.
      real(8), private :: hs10 ; logical, private :: ok_hs10 = .false.
      real(8), private :: Ts0 ; logical, private :: ok_Ts0 = .false.
      real(8), private :: Tb0 ; logical, private :: ok_Tb0 = .false.
      real(8), private :: Tbb0 ; logical, private :: ok_Tbb0 = .false.
      real(8), private :: h_ML0 ; logical, private :: ok_h_ML0 = .false.
      real(8), private :: extwat ; logical, private :: ok_extwat = .false.
      real(8), private :: extice ; logical, private :: ok_extice = .false.
      real(8), private :: kor ; logical, private :: ok_kor = .false.
      real(8), private :: trib_inflow ; logical, private :: ok_trib_inflow = .false.
      real(8), private :: Sals0 ; logical, private :: ok_Sals0 = .false.
      real(8), private :: Salb0 ; logical, private :: ok_Salb0 = .false.
      real(8), private :: fetch ; logical, private :: ok_fetch = .false.
      real(8), private :: phi ; logical, private :: ok_phi = .false.
      real(8), private :: lam ; logical, private :: ok_lam = .false.
      real(8), private :: us0 ; logical, private :: ok_us0 = .false.
      real(8), private :: vs0 ; logical, private :: ok_vs0 = .false.
      real(8), private :: Tm ; logical, private :: ok_Tm = .false.
      real(8), private :: alphax ; logical, private :: ok_alphax = .false.
      real(8), private :: alphay ; logical, private :: ok_alphay = .false.
      real(8), private :: a_veg ; logical, private :: ok_a_veg = .false.
      real(8), private :: c_veg ; logical, private :: ok_c_veg = .false.
      real(8), private :: h_veg ; logical, private :: ok_h_veg = .false.
      real(8), private :: area_lake ; logical, private :: ok_area_lake = .false.
      real(8), private :: spinup_period ; logical, private :: ok_spinup_period = .false.

      real(8), private :: select_extwat(1:n_select_call)
      real(8), private :: select_h10(1:n_select_call)

      integer(4), private :: init_T ; logical, private :: ok_init_T = .false.
      integer(4), private :: year0 ; logical, private :: ok_year0 = .false.
      integer(4), private :: month0 ; logical, private :: ok_month0 = .false.
      integer(4), private :: day0 ; logical, private :: ok_day0 = .false.
      integer(4), private :: forc_format ; logical, private :: ok_forc_format = .false.
      integer(4), private :: form ; logical, private :: ok_form = .false.
      integer(4), private :: spinup_times ; logical, private :: ok_spinup_times = .false.
      integer(4), private :: rad ; logical, private :: ok_rad = .false.
      integer(4), private :: N_header_lines ; logical, private :: ok_N_header_lines = .false.
      integer(4), private :: N_coloumns ; logical, private :: ok_N_coloumns = .false.
      integer(4), private :: N_Year ; logical, private :: ok_N_Year = .false.
      integer(4), private :: N_Month ; logical, private :: ok_N_Month = .false.
      integer(4), private :: N_Day ; logical, private :: ok_N_Day = .false.
      integer(4), private :: N_Hour ; logical, private :: ok_N_Hour = .false.
      integer(4), private :: N_Precip ; logical, private :: ok_N_Precip = .false.
      integer(4), private :: N_Uspeed ; logical, private :: ok_N_Uspeed = .false.
      integer(4), private :: N_Vspeed ; logical, private :: ok_N_Vspeed = .false.
      integer(4), private :: N_Temp ; logical, private :: ok_N_Temp = .false.
      integer(4), private :: N_Hum ; logical, private :: ok_N_Hum = .false.
      integer(4), private :: N_Pres ; logical, private :: ok_N_Pres = .false.
      integer(4), private :: N_SWdown ; logical, private :: ok_N_SWdown = .false.
      integer(4), private :: N_LWdown ; logical, private :: ok_N_LWdown = .false.
      integer(4), private :: npoints ; logical, private :: ok_npoints = .false.
      integer(4), private :: nstep_ncout ; logical, private :: ok_nstep_ncout = .false.
      integer(4), private :: call_FLake ; logical, private :: ok_call_FLake = .false.
      integer(4), private :: moving_average_window ; logical, private :: ok_moving_average_window = .false.
      integer(4), private :: mean_cycle_period ; logical, private :: ok_mean_cycle_period = .false.
      integer(4), private :: nstep_out_Flake ; logical, private :: ok_nstep_out_Flake = .false.
 
      integer(4), private :: select_call(1:n_select_call)

      character(len=60), private :: dataname ; logical, private :: ok_dataname = .false.

      logical, private :: screenout = .false.
     
      contains



      SUBROUTINE DEFPARDRIVER &
     & (hour0_outt, tinteg_outt, dt_outt, height_T_q_outt, height_u_outt, interval_outt, &
     &  h10_outt, select_h10_outt, l10_outt, ls10_outt, hs10_outt, Ts0_outt, &
     &  Tb0_outt, Tbb0_outt, h_ML0_outt, &
     &  extwat_outt, select_extwat_outt, extice_outt, &
     &  kor_outt, trib_inflow_outt, Sals0_outt, Salb0_outt, fetch_outt, phi_outt, &
     &  lam_outt, us0_outt, vs0_outt, &
     &  Tm_outt, alphax_outt, alphay_outt, a_veg_outt, c_veg_outt, &
     &  h_veg_outt, area_lake_outt, &
     &  year0_outt, month0_outt, day0_outt, npoints_outt, select_call_outt, &
     &  forc_format_outt, form_outt, &
     &  spinup_times_outt, spinup_period_outt, rad_outt, &
     &  N_header_lines_outt, N_coloumns_outt, N_Year_outt, N_Month_outt, &
     &  N_Day_outt, N_Hour_outt, N_Precip_outt, N_Uspeed_outt, N_Vspeed_outt, &
     &  N_Temp_outt, N_Hum_outt, N_Pres_outt, N_SWdown_outt, N_LWDown_outt, &
     &  nstep_ncout_outt, &
     &  init_T_outt, call_Flake_outt, moving_average_window_outt, mean_cycle_period_outt, &
     &  nstep_out_Flake_outt, dataname_outt)
      
!     DEFPARDRIVER reads file with driving parameters

      implicit none
      
      real(8), intent(out), optional :: hour0_outt
      real(8), intent(out), optional :: tinteg_outt
      real(8), intent(out), optional :: dt_outt
      real(8), intent(out), optional :: height_T_q_outt
      real(8), intent(out), optional :: height_u_outt
      real(8), intent(out), optional :: interval_outt
      
      real(8), intent(out), optional :: h10_outt
      real(8), intent(out), optional :: l10_outt
      real(8), intent(out), optional :: ls10_outt
      real(8), intent(out), optional :: hs10_outt
      real(8), intent(out), optional :: Ts0_outt
      real(8), intent(out), optional :: Tb0_outt
      real(8), intent(out), optional :: Tbb0_outt
      real(8), intent(out), optional :: h_ML0_outt
      real(8), intent(out), optional :: extwat_outt
      real(8), intent(out), optional :: extice_outt
      real(8), intent(out), optional :: kor_outt
      real(8), intent(out), optional :: trib_inflow_outt
      real(8), intent(out), optional :: Sals0_outt
      real(8), intent(out), optional :: Salb0_outt
      real(8), intent(out), optional :: fetch_outt
      real(8), intent(out), optional :: phi_outt
      real(8), intent(out), optional :: lam_outt
      real(8), intent(out), optional :: us0_outt
      real(8), intent(out), optional :: vs0_outt
      real(8), intent(out), optional :: Tm_outt
      real(8), intent(out), optional :: alphax_outt
      real(8), intent(out), optional :: alphay_outt
      real(8), intent(out), optional :: a_veg_outt
      real(8), intent(out), optional :: c_veg_outt
      real(8), intent(out), optional :: h_veg_outt
      real(8), intent(out), optional :: area_lake_outt
      real(8), intent(out), optional :: spinup_period_outt

      real(8), intent(out), optional :: select_extwat_outt(1:n_select_call)
      real(8), intent(out), optional :: select_h10_outt(1:n_select_call)

      integer(4), intent(out), optional :: init_T_outt
      integer(4), intent(out), optional :: year0_outt
      integer(4), intent(out), optional :: month0_outt
      integer(4), intent(out), optional :: day0_outt
      integer(4), intent(out), optional :: forc_format_outt
      integer(4), intent(out), optional :: form_outt
      integer(4), intent(out), optional :: spinup_times_outt
      integer(4), intent(out), optional :: rad_outt
      integer(4), intent(out), optional :: N_header_lines_outt
      integer(4), intent(out), optional :: N_coloumns_outt
      integer(4), intent(out), optional :: N_Year_outt
      integer(4), intent(out), optional :: N_Month_outt
      integer(4), intent(out), optional :: N_Day_outt
      integer(4), intent(out), optional :: N_Hour_outt
      integer(4), intent(out), optional :: N_Precip_outt
      integer(4), intent(out), optional :: N_Uspeed_outt
      integer(4), intent(out), optional :: N_Vspeed_outt
      integer(4), intent(out), optional :: N_Temp_outt
      integer(4), intent(out), optional :: N_Hum_outt
      integer(4), intent(out), optional :: N_Pres_outt
      integer(4), intent(out), optional :: N_SWdown_outt
      integer(4), intent(out), optional :: N_LWdown_outt
      integer(4), intent(out), optional :: npoints_outt
      integer(4), intent(out), optional :: nstep_ncout_outt
      integer(4), intent(out), optional :: call_FLake_outt
      integer(4), intent(out), optional :: moving_average_window_outt
      integer(4), intent(out), optional :: mean_cycle_period_outt
      integer(4), intent(out), optional :: nstep_out_Flake_outt
 
      integer(4), intent(out), optional :: select_call_outt(1:n_select_call)

      character(len=60), intent(out), optional :: dataname_outt
      
!     Local variables      

      character(len=60)  :: driver_file
      
      logical, save :: firstcall = .true.
      logical, save :: all_par_set = .true.
      
      if (firstcall) then
       call CHECK_UNIT(driver_subr_unit_min,driver_subr_unit_max,nunit)            
       open  (nunit,file='driver_lake.dat',status='old')
       read  (nunit,'(a)') line
       read  (nunit,'(a)') driver_file
       close (nunit)
       open  (nunit,file=driver_file,status='old')
       do while (line /= 'end')
         read (nunit,'(a)') line
         call READPARDRIVER()
       enddo
       close (nunit)
       

      if (.not.PAR_SET_REAL8(hour0,ok_hour0,hour0_outt)) &
      & call WRITE_PAR_NOT_SET('hour0')
      if (.not.PAR_SET_REAL8(tinteg,ok_tinteg,tinteg_outt)) &
      & call WRITE_PAR_NOT_SET('tinteg')
      if (.not.PAR_SET_REAL8(dt,ok_dt,dt_outt)) &
      & call WRITE_PAR_NOT_SET('dt')
      if (.not.PAR_SET_REAL8(height_T_q,ok_height_T_q,height_T_q_outt)) &
      & call WRITE_PAR_NOT_SET('height_T_q')
      if (.not.PAR_SET_REAL8(height_u,ok_height_u,height_u_outt)) &
      & call WRITE_PAR_NOT_SET('height_u')
      if (.not.PAR_SET_REAL8(interval,ok_interval,interval_outt)) &
      & call WRITE_PAR_NOT_SET('interval')
      
      if (.not.PAR_SET_REAL8(h10,ok_h10,h10_outt)) &
      & call WRITE_PAR_NOT_SET('h10')
      if (.not.PAR_SET_REAL8(l10,ok_l10,l10_outt)) &
      & call WRITE_PAR_NOT_SET('l10')
      if (.not.PAR_SET_REAL8(ls10,ok_ls10,ls10_outt)) &
      & call WRITE_PAR_NOT_SET('ls10')
      if (.not.PAR_SET_REAL8(hs10,ok_hs10,hs10_outt)) &
      & call WRITE_PAR_NOT_SET('hs10')
      if (.not.PAR_SET_REAL8(Ts0,ok_Ts0,Ts0_outt)) &
      & call WRITE_PAR_NOT_SET('Ts0')
      if (.not.PAR_SET_REAL8(Tb0,ok_Tb0,Tb0_outt)) &
      & call WRITE_PAR_NOT_SET('Tb0')
      if (.not.PAR_SET_REAL8(Tbb0,ok_Tbb0,Tbb0_outt)) &
      & call WRITE_PAR_NOT_SET('Tbb0')
      if (.not.PAR_SET_REAL8(h_ML0,ok_h_ML0,h_ML0_outt)) &
      & call WRITE_PAR_NOT_SET('h_ML0')
      if (.not.PAR_SET_REAL8(extwat,ok_extwat,extwat_outt)) &
      & call WRITE_PAR_NOT_SET('extwat')
      if (.not.PAR_SET_REAL8(extice,ok_extice,extice_outt)) &
      & call WRITE_PAR_NOT_SET('extice')
      if (.not.PAR_SET_REAL8(kor,ok_kor,kor_outt)) &
      & call WRITE_PAR_NOT_SET('kor')
      if (.not.PAR_SET_REAL8(trib_inflow,ok_trib_inflow,trib_inflow_outt)) &
      & call WRITE_PAR_NOT_SET('trib_inflow')
      if (.not.PAR_SET_REAL8(Sals0,ok_Sals0,Sals0_outt)) &
      & call WRITE_PAR_NOT_SET('Sals0')
      if (.not.PAR_SET_REAL8(Salb0,ok_Salb0,Salb0_outt)) &
      & call WRITE_PAR_NOT_SET('Salb0')
      if (.not.PAR_SET_REAL8(fetch,ok_fetch,fetch_outt)) &
      & call WRITE_PAR_NOT_SET('fetch')
      if (.not.PAR_SET_REAL8(phi,ok_phi,phi_outt)) &
      & call WRITE_PAR_NOT_SET('phi')
      if (.not.PAR_SET_REAL8(lam,ok_lam,lam_outt)) &
      & call WRITE_PAR_NOT_SET('lam')
      if (.not.PAR_SET_REAL8(us0,ok_us0,us0_outt)) &
      & call WRITE_PAR_NOT_SET('us0')
      if (.not.PAR_SET_REAL8(vs0,ok_vs0,vs0_outt)) &
      & call WRITE_PAR_NOT_SET('vs0')
      if (.not.PAR_SET_REAL8(Tm,ok_Tm,Tm_outt)) &
      & call WRITE_PAR_NOT_SET('Tm')
      if (.not.PAR_SET_REAL8(alphax,ok_alphax,alphax_outt)) &
      & call WRITE_PAR_NOT_SET('alphax')
      if (.not.PAR_SET_REAL8(alphay,ok_alphay,alphay_outt)) &
      & call WRITE_PAR_NOT_SET('alphay')
      if (.not.PAR_SET_REAL8(a_veg,ok_a_veg,a_veg_outt)) &
      & call WRITE_PAR_NOT_SET('a_veg')
      if (.not.PAR_SET_REAL8(c_veg,ok_c_veg,c_veg_outt)) &
      & call WRITE_PAR_NOT_SET('c_veg')
      if (.not.PAR_SET_REAL8(h_veg,ok_h_veg,h_veg_outt)) &
      & call WRITE_PAR_NOT_SET('h_veg')
      if (.not.PAR_SET_REAL8(area_lake,ok_area_lake,area_lake_outt)) &
      & call WRITE_PAR_NOT_SET('area_lake')
      if (.not.PAR_SET_REAL8(spinup_period,ok_spinup_period,spinup_period_outt)) &
      & call WRITE_PAR_NOT_SET('spinup_period')

      select_extwat_outt = select_extwat
      select_h10_outt = select_h10

      if (.not.PAR_SET_INTEGER4(init_T,ok_init_T,init_T_outt)) &
      & call WRITE_PAR_NOT_SET('init_T')
      if (.not.PAR_SET_INTEGER4(year0,ok_year0,year0_outt)) &
      & call WRITE_PAR_NOT_SET('year0')
      if (.not.PAR_SET_INTEGER4(month0,ok_month0,month0_outt)) &
      & call WRITE_PAR_NOT_SET('month0')
      if (.not.PAR_SET_INTEGER4(day0,ok_day0,day0_outt)) &
      & call WRITE_PAR_NOT_SET('day0')
      if (.not.PAR_SET_INTEGER4(forc_format,ok_forc_format,forc_format_outt)) &
      & call WRITE_PAR_NOT_SET('forc_format')
      if (.not.PAR_SET_INTEGER4(form,ok_form,form_outt)) &
      & call WRITE_PAR_NOT_SET('form')
      if (.not.PAR_SET_INTEGER4(spinup_times,ok_spinup_times, spinup_times_outt)) &
      & call WRITE_PAR_NOT_SET('spinup_times')
      if (.not.PAR_SET_INTEGER4(rad, ok_rad, rad_outt)) &
      & call WRITE_PAR_NOT_SET('rad')
      if (.not.PAR_SET_INTEGER4(N_header_lines, ok_N_header_lines, N_header_lines_outt)) &
      & call WRITE_PAR_NOT_SET('N_header_lines')
      if (.not.PAR_SET_INTEGER4(N_coloumns, ok_N_coloumns, N_coloumns_outt)) &
      & call WRITE_PAR_NOT_SET('N_coloumns')
      if (.not.PAR_SET_INTEGER4(N_Year, ok_N_Year, N_Year_outt)) &
      & call WRITE_PAR_NOT_SET('N_Year')
      if (.not.PAR_SET_INTEGER4(N_Month, ok_N_Month, N_Month_outt)) &
      & call WRITE_PAR_NOT_SET('N_Month')
      if (.not.PAR_SET_INTEGER4(N_Day, ok_N_Day, N_Day_outt)) &
      & call WRITE_PAR_NOT_SET('N_Day')
      if (.not.PAR_SET_INTEGER4(N_Hour, ok_N_Hour, N_Hour_outt)) &
      & call WRITE_PAR_NOT_SET('N_Hour')
      if (.not.PAR_SET_INTEGER4(N_Precip, ok_N_Precip, N_Precip_outt)) &
      & call WRITE_PAR_NOT_SET('N_Precip')
      if (.not.PAR_SET_INTEGER4(N_Uspeed, ok_N_Uspeed, N_Uspeed_outt)) &
      & call WRITE_PAR_NOT_SET('N_Uspeed')
      if (.not.PAR_SET_INTEGER4(N_Vspeed, ok_N_Vspeed, N_Vspeed_outt)) &
      & call WRITE_PAR_NOT_SET('N_Vspeed')
      if (.not.PAR_SET_INTEGER4(N_Temp, ok_N_Temp, N_Temp_outt)) &
      & call WRITE_PAR_NOT_SET('N_Temp')
      if (.not.PAR_SET_INTEGER4(N_Hum, ok_N_Hum, N_Hum_outt)) &
      & call WRITE_PAR_NOT_SET('N_Hum')
      if (.not.PAR_SET_INTEGER4(N_Pres, ok_N_Pres, N_Pres_outt)) &
      & call WRITE_PAR_NOT_SET('N_Pres')
      if (.not.PAR_SET_INTEGER4(N_SWdown, ok_N_SWdown, N_SWdown_outt)) &
      & call WRITE_PAR_NOT_SET('N_SWdown')
      if (.not.PAR_SET_INTEGER4(N_LWdown, ok_N_LWdown, N_LWdown_outt)) &
      & call WRITE_PAR_NOT_SET('N_LWdown')
      if (.not.PAR_SET_INTEGER4(npoints, ok_npoints, npoints_outt)) &
      & call WRITE_PAR_NOT_SET('npoints')
      if (.not.PAR_SET_INTEGER4(nstep_ncout, ok_nstep_ncout, nstep_ncout_outt)) &
      & call WRITE_PAR_NOT_SET('nstep_ncout')
      if (.not.PAR_SET_INTEGER4(call_FLake, ok_call_FLake, call_FLake_outt)) &
      & call WRITE_PAR_NOT_SET('call_FLake')
      if (.not.PAR_SET_INTEGER4(moving_average_window, ok_moving_average_window, moving_average_window_outt)) &
      & call WRITE_PAR_NOT_SET('moving_average_window')
      if (.not.PAR_SET_INTEGER4(mean_cycle_period, ok_mean_cycle_period, mean_cycle_period_outt)) &
      & call WRITE_PAR_NOT_SET('mean_cycle_period')
      if (.not.PAR_SET_INTEGER4(nstep_out_Flake, ok_nstep_out_Flake, nstep_out_Flake_outt)) &
      & call WRITE_PAR_NOT_SET('nstep_out_Flake')
 
      select_call_outt = select_call

      if (ok_dataname) then
        dataname_outt = dataname
      else
        write (*,*) 'The parameter dataname is not set in driver file'
        all_par_set = .false.
      endif
      
      if (.not.all_par_set) then
        write (*,*) &
        & 'Not all necessary parameters are set in driver file: STOP' 
        STOP
      endif
       
       firstcall = .false. 
      endif

      contains
      FUNCTION PAR_SET_REAL8(par,ok_par,par_outt)
      implicit none
      
      logical :: PAR_SET_REAL8
      
!     Input variables
      real(8), intent(in) :: par
      logical, intent(in) :: ok_par
      
!     Output variables
      real(8), intent(out) :: par_outt
            
      if (ok_par) par_outt = par
      PAR_SET_REAL8 = ok_par
      
      END FUNCTION PAR_SET_REAL8
      
      FUNCTION PAR_SET_INTEGER4(par,ok_par,par_outt)
      implicit none
      
      logical :: PAR_SET_INTEGER4
      
!     Input variables
      integer(4), intent(in) :: par
      logical, intent(in) :: ok_par
      
!     Output variables
      integer(4), intent(out) :: par_outt
            
      if (ok_par) par_outt = par
      PAR_SET_INTEGER4 = ok_par
      
      END FUNCTION PAR_SET_INTEGER4
      
      SUBROUTINE WRITE_PAR_NOT_SET(variable_name)
      implicit none
      
!     Input variables
      character(len=*), intent(in) :: variable_name
      
      write (*,*) 'The parameter ', &
      & variable_name(1:len_trim(variable_name)), &
      & ' is not set in driver file'
      
      all_par_set = .false.
      
      END SUBROUTINE WRITE_PAR_NOT_SET
      END SUBROUTINE DEFPARDRIVER
      
      
      SUBROUTINE READPARDRIVER()
     
      implicit none

!     Local variables
      real(8), allocatable :: work1(:,:)
      
      integer(4) :: i
      integer(4) :: n2
      integer(4) :: n1
      integer(4) :: nselect

      logical, save :: firstcall = .true.
      
!     External functions
      real(8),    external :: getvarval
      integer(4), external :: igetvarval

      if (firstcall) then
        select_call(:) = -1
        select_extwat(:) = -1
        select_h10(:) = -1
      endif

      i=1
      if (line(1:1)==' '.or.line(1:1)==char(1)) then
        do while (line(i:i)==' '.or.line(i:i)==char(1))
          i=i+1
        enddo
        n1=i
        do while (line(i:i)/=' '.and.line(i:i)/=char(1))
          i=i+1
        enddo
        n2=i-1
      else
        n1=1
        do while (line(i:i)/=' '.and.line(i:i)/=char(1))
          i=i+1
        enddo
        n2=i-1
      endif
      
      if (line(n1:n1)/='#') then
      
       SELECT CASE (line(n1:n2))

!     The parameters of time integration

       CASE ('call_Flake')
        call_Flake &
     &           = igetvarval(n1,n2,line,'The year of start integr.') 
        ok_call_Flake = .true.
       CASE ('year0')
        year0    = igetvarval(n1,n2,line,'The year of start integr.') 
        ok_year0 = .true.
       CASE ('month0')
        month0   = igetvarval(n1,n2,line,'The month of start integ.')
        ok_month0 = .true.
       CASE ('day0')
        day0     = igetvarval(n1,n2,line,'The day of start integ.  ')
        ok_day0 = .true.
       CASE ('hour0')
        hour0    = getvarval (n1,n2,line,'Initial hour             ')
        ok_hour0 = .true.
       CASE ('tinteg')
        tinteg   = getvarval (n1,n2,line,'Integration time, days   ')
        ok_tinteg = .true.
       CASE ('spinup_times')
        spinup_times &
     &           = igetvarval(n1,n2,line,'Spinup, days             ')
        ok_spinup_times = .true.
       CASE ('spinup_period')
        spinup_period &
     &           = getvarval (n1,n2,line,'Spinup period, sec       ')
        ok_spinup_period = .true.
       CASE ('dt')
        dt       = getvarval (n1,n2,line,'Timestep, sec            ')
        ok_dt = .true.

!     The group of parameters of forcing file 

       CASE ('npoints')
        npoints  = igetvarval(n1,n2,line,'The number of points     ')
        ok_npoints = .true.
       CASE ('select_call')
        nselect  = igetvarval(n1,n2,line,'Number of selected points')
        allocate (work1(1:nselect,1))
        call READPROFILE(nunit,nselect,1,work1)
        select_call(1:nselect) = int(work1(1:nselect,1))
        deallocate(work1)
!        ok_nselect = .true.
       CASE ('forc_format')
        forc_format &
     &           = igetvarval(n1,n2,line,'Format of input file     ')
        ok_forc_format = .true.
       CASE ('form')
        form     = igetvarval(n1,n2,line,'Format of ASCII file     ')
        ok_form = .true.
       CASE ('dataname')
        read (line((n2+1):100),*) dataname
!        print*, 'dataname = ', dataname 
        ok_dataname = .true.
       CASE ('height_T_q')
        height_T_q &
     &           = getvarval (n1,n2,line,'Height of t&q measur-ts  ')
        ok_height_T_q = .true.
       CASE ('height_u')
        height_u = getvarval (n1,n2,line,'Height of wind measur-ts ')
        ok_height_u = .true.
       CASE ('interval')
        interval = getvarval (n1,n2,line,'Time interval of input   ')
        ok_interval = .true.
       CASE ('rad')
        rad      = igetvarval(n1,n2,line,'Input of radiation       ')
        ok_rad = .true.

!     The group of input text file format parameters

       CASE ('N_header_lines')
        N_header_lines &
     &           = igetvarval(n1,n2,line,'N_header_lines           ')
        ok_N_header_lines = .true.
       CASE ('N_coloumns')
        N_coloumns &
     &           = igetvarval(n1,n2,line,'N_Coloumns               ')
        ok_N_coloumns = .true.
       CASE ('N_Year')
        N_Year   = igetvarval(n1,n2,line,'N_Year                   ')
        ok_N_Year = .true.
       CASE ('N_Month')
        N_Month  = igetvarval(n1,n2,line,'N_Month                  ')
        ok_N_Month = .true.
       CASE ('N_Day')
        N_Day    = igetvarval(n1,n2,line,'N_Day                    ')
        ok_N_Day = .true.
       CASE ('N_Hour')
        N_Hour   = igetvarval(n1,n2,line,'N_Hour                   ')
        ok_N_Hour = .true.
       CASE ('N_Precip')
        N_Precip = igetvarval(n1,n2,line,'N_Precip                 ')
        ok_N_Precip = .true.
       CASE ('N_Uspeed')
        N_Uspeed = igetvarval(n1,n2,line,'N_Uspeed                 ')
        ok_N_Uspeed = .true.
       CASE ('N_Vspeed')
        N_Vspeed = igetvarval(n1,n2,line,'N_Vspeed                 ')
        ok_N_Vspeed = .true.
       CASE ('N_Temp')
        N_Temp   = igetvarval(n1,n2,line,'N_Temp                   ')
        ok_N_Temp = .true.
       CASE ('N_Hum')
        N_Hum    = igetvarval(n1,n2,line,'N_Hum                    ')
        ok_N_Hum = .true.
       CASE ('N_Pres')
        N_Pres   = igetvarval(n1,n2,line,'N_Pres                   ')
        ok_N_Pres = .true.
       CASE ('N_SWdown')
        N_SWdown = igetvarval(n1,n2,line,'N_SWdown                 ')
        ok_N_SWdown = .true.
       CASE ('N_LWdown')
        N_LWdown = igetvarval(n1,n2,line,'N_LWdown                 ')
        ok_N_LWdown = .true.        
       CASE ('h10')
        h10      = getvarval (n1,n2,line,'Init. depth of lake, m   ')
        ok_h10 = .true.
       CASE ('select_h10')
        nselect  = igetvarval(n1,n2,line,'Number of selected depths')
        allocate (work1(1:nselect,1:2))
        call READPROFILE(nunit,nselect,2,work1)
        do i = 1, nselect
          if (int(work1(i,1)) /= select_call(i)) then
            write(*,*) 'select_h10 must be set in the order of selected points: &
            & terminating program'
            STOP
          endif
        enddo
        select_h10(1:nselect) = work1(1:nselect,2)
        deallocate(work1)
!        ok_nselect = .true.
       CASE ('l10')
        l10      = getvarval (n1,n2,line,'Init. ice thickness, m   ')
        ok_l10 = .true.
       CASE ('ls10')
        ls10     = getvarval (n1,n2,line,'Init. deep ice thick., m ')
        ok_ls10 = .true.
       CASE ('hs10')
        hs10     = getvarval (n1,n2,line,'Init. snow depth, m      ')
        ok_hs10 = .true.
       CASE ('Ts0')
        Ts0      = getvarval (n1,n2,line,'Init. temp. at lake surf.')
        ok_Ts0 = .true.
       CASE ('Tb0')
        Tb0      = getvarval (n1,n2,line,'Init. temp. at lake bot. ')
        ok_Tb0 = .true.
       CASE ('Tbb0')
        Tbb0     = getvarval (n1,n2,line,'Init. temp. at soil bot. ')
        ok_Tbb0 = .true.
       CASE ('h_ML0')
        h_ML0    = getvarval (n1,n2,line,'Init. mixed layer depth  ')
        ok_h_ML0 = .true.
       CASE ('Tm')
        Tm       = getvarval (n1,n2,line,'Mean coloumn temperature ')
        ok_Tm = .true.
       CASE ('init_T')
        init_T   = igetvarval(n1,n2,line,'Switch for temp. init.   ')
        ok_init_T = .true.
       CASE ('Sals0')
        Sals0    = getvarval (n1,n2,line,'Init. surface salinity   ')
        ok_Sals0 = .true.
       CASE ('Salb0')
        Salb0    = getvarval (n1,n2,line,'Init. bottom salinity    ')
        ok_Salb0 = .true.
       CASE ('us0')
        us0      = getvarval (n1,n2,line,'Init. surface X-speed    ')
        ok_us0 = .true.
       CASE ('vs0')
        vs0      = getvarval (n1,n2,line,'Init. surface Y-speed    ')
        ok_vs0 = .true.
       CASE ('kor')
        kor      = getvarval (n1,n2,line,'The Coriolis parameter   ')
        ok_kor = .true.
       CASE ('phi')
        phi      = getvarval (n1,n2,line,'Latitude, deg            ')
        ok_phi = .true.
       CASE ('lam')
        lam      = getvarval (n1,n2,line,'Longitude, deg           ') 
        ok_lam = .true.
       CASE ('extwat')
        extwat   = getvarval (n1,n2,line,'The rad extinct in water ')
        ok_extwat = .true.
       CASE ('select_extwat')
        nselect  = igetvarval(n1,n2,line,'Number of selected extwat')
        allocate (work1(1:nselect,1:2))
        call READPROFILE(nunit,nselect,2,work1)
        do i = 1, nselect
          if (int(work1(i,1)) /= select_call(i)) then
            write(*,*) 'select_extwat must be set in the order of selected points: &
            & terminating program'
            STOP
          endif
        enddo
        select_extwat(1:nselect) = work1(1:nselect,2)
        deallocate(work1)
!        ok_ = .true.
       CASE ('extice')
        extice   = getvarval (n1,n2,line,'The rad extinction in ice')
        ok_extice = .true.
       CASE ('alphax')
        alphax   = getvarval (n1,n2,line,'The x-slope angle        ')
        ok_alphax = .true.
       CASE ('alphay')
        alphay   = getvarval (n1,n2,line,'The y-slope angle        ')
        ok_alphay = .true.
       CASE ('c_veg')
        c_veg    = getvarval (n1,n2,line,'c_veg                    ')
        ok_c_veg = .true.
       CASE ('a_veg')
        a_veg    = getvarval (n1,n2,line,'a_veg                    ')
        ok_a_veg = .true.
       CASE ('h_veg')
        h_veg    = getvarval (n1,n2,line,'The vegetation height    ')
        ok_h_veg = .true.
       CASE ('fetch')
        fetch    = getvarval (n1,n2,line,'The fetch, m             ')
        ok_fetch = .true.
       CASE ('trib_inflow')
        trib_inflow &
     &           = getvarval (n1,n2,line,'Tributary inflow, m/yr   ')
        ok_trib_inflow = .true.
       CASE ('area_lake')
        area_lake= getvarval (n1,n2,line,'The area of lake, m**2   ')
        ok_area_lake = .true.
       
!      The group of parameters for netcdf output from driver

       CASE ('nstep_ncout')
        nstep_ncout &
     &           = igetvarval(n1,n2,line,'Nstep for netcdf output  ')
        ok_nstep_ncout = .true.
       CASE ('nstep_out_Flake')
        nstep_out_Flake &
     &           = igetvarval(n1,n2,line,'Nstep for Flake output   ')
        ok_nstep_out_Flake = .true.

!      The group of parameters for postprocessing
       CASE ('moving_average_window')
        moving_average_window &
     &           = igetvarval(n1,n2,line,'Moving average window    ')
        ok_moving_average_window = .true.
       CASE ('mean_cycle_period')
        mean_cycle_period &
     &           = igetvarval(n1,n2,line,'Mean cycle period        ')
        ok_mean_cycle_period = .true.

       CASE DEFAULT
        if (.not.line(n1:n2)=='end') then
         print*,'Unknown keyword [',line(n1:n2),'] in setup file: STOP'
         STOP
        endif
       END SELECT

      endif

      if (firstcall) firstcall = .false.
      CONTAINS

      SUBROUTINE READPROFILE(iunit,N_rows,N_coloumns,work)
      implicit none

!     Input variables:
      integer(4), intent(in) :: iunit
      integer(4), intent(in) :: N_rows
      integer(4), intent(in) :: N_coloumns

!     Output variables:
      real(8), intent(out) :: work(N_rows, N_coloumns)

!     Local variables
      integer(4) :: i
      integer(4) :: j

      do i=1, N_rows
        read(iunit,*) (work(i,j), j=1,N_coloumns)
      enddo

      END SUBROUTINE READPROFILE
      END SUBROUTINE READPARDRIVER    

      END MODULE LAKE_DRIVER_PARAMETERS
